/**
 * Copyright 2018-2019 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.fos.oss;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.jianggujin.fos.JFOSLazyException;
import com.jianggujin.fos.JSecurityToken;
import com.jianggujin.fos.JSecurityTokenService;
import com.jianggujin.fos.oss.JOSSConfiguration.JOSSSessionTokenConfiguration;

import lombok.NonNull;

/**
 * @author jianggujin
 *
 */
public class JOSSSecurityTokenService implements JSecurityTokenService {
    // String endpoint = "sts.aliyuncs.com";
    // private JOSSConfiguration configuration;
    private DefaultAcsClient client = null;
    private AssumeRoleRequest request = null;

    static {
        try {
            DefaultProfile.addEndpoint("", "", "Sts", "sts.aliyuncs.com");
        } catch (ClientException e) {
        }
    }

    public JOSSSecurityTokenService(@NonNull JOSSConfiguration configuration) {
        // this.configuration = configuration;
        // 构造default profile（参数留空，无需添加region ID）
        IClientProfile profile = DefaultProfile.getProfile("", configuration.getAccessKeyId(),
                configuration.getSecretAccessKey());
        JOSSSessionTokenConfiguration sessionTokenConfiguration = configuration.getSessionTokenConfiguration();
        // 用profile构造client
        client = new DefaultAcsClient(profile);
        request = new AssumeRoleRequest();
        request.setRoleArn(sessionTokenConfiguration.getRoleArn());
        request.setRoleSessionName(sessionTokenConfiguration.getRoleSessionName());
        request.setPolicy(sessionTokenConfiguration.getPolicy()); // Optional
    }

    @Override
    public JSecurityToken getSecurityToken() {

        // String roleArn = "<role-arn>";
        // String roleSessionName = "session-name";
        // String policy = "{\n" + " \"Version\": \"1\", \n" + " \"Statement\": [\n" + "
        // {\n"
        // + " \"Action\": [\n" + " \"oss:*\"\n" + " ], \n"
        // + " \"Resource\": [\n" + " \"acs:oss:*:*:*\" \n" + " ], \n"
        // + " \"Effect\": \"Allow\"\n" + " }\n" + " ]\n" + "}";
        try {
            AssumeRoleResponse response = client.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();
            return new JSecurityToken(credentials.getAccessKeyId(), credentials.getAccessKeySecret(),
                    credentials.getSecurityToken(), parseUTCText(credentials.getExpiration()).getTime());
        } catch (Exception e) {
            throw new JFOSLazyException(e.getMessage(), e);
        }
    }

    public static Date parseUTCText(String text) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        if (text.indexOf(".") > -1) {
            String prefix = text.substring(0, text.indexOf("."));
            String suffix = text.substring(text.indexOf("."));
            if (suffix.length() >= 5) {
                suffix = suffix.substring(0, 4) + "Z";
            } else {
                int len = 5 - suffix.length();
                String temp = "";
                temp += suffix.substring(0, suffix.length() - 1);
                for (int i = 0; i < len; i++) {
                    temp += "0";
                }
                suffix = temp + "Z";
            }
            text = prefix + suffix;
        } else {
            text = text.substring(0, text.length() - 1) + ".000Z";
        }
        Date date = sdf.parse(text);
        return date;
    }

    @Override
    public void destory() {
    }

}
